use std::collections::HashMap;

use derive_builder::Builder;
use serde::{Deserialize, Serialize};

use crate::database::DatabaseType;
use crate::error::Error;
use crate::modeling::Value;

#[derive(Debug, Default, Serialize, Deserialize, Clone, PartialEq)]
pub enum CodeLanguage {
    #[default]
    Rust,
    Java,
    Python,
    Typescript,
    Sql(DatabaseType),
}

#[derive(Debug, Default, Serialize, Deserialize, Clone, PartialEq)]
pub struct CodeGeneratorOption {}

#[async_trait::async_trait]
pub trait CodeGenerator {
    /// 生成代码
    async fn generate(
        &self,
        language: CodeLanguage,
        data_context: Value,
        template_dir: &str,
        files: &Vec<String>,
        dist_dir: &str,
        options: CodeGeneratorOption,
    ) -> anyhow::Result<()>;

    /// 生成代码
    async fn generate_string(
        &self,
        language: CodeLanguage,
        data_context: Value,
        template: &str,
        options: CodeGeneratorOption,
    ) -> anyhow::Result<String>;

    /// 生成代码
    async fn simple(&self, data_context: Value, template: &str) -> anyhow::Result<String>;
}

#[derive(Debug, Default, Serialize, Deserialize, Clone, PartialEq)]
pub struct SqlGeneratorOption {}

pub trait SqlGenerator {
    /// 生成代码
    fn generate(
        &self,
        database_type: DatabaseType,
        template_dir: &str,
        files: &Vec<String>,
        dist_dir: &str,
        options: SqlGeneratorOption,
    ) -> anyhow::Result<()>;
}
